package main

import "fmt"

func main() {
	// 切片 是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。它非常灵活，支持自动扩容。
	// 切片是一个引用类型，它的内部结构包括 地址 长度和容量。 切片一般用于快速的操作一块数据集合。

	// 定义切片
	var s1 []int    // 定义一个存放int类型元素的切片
	var s2 []string // 定义一个存放string类型的元素切片
	fmt.Println(s1, s2)
	fmt.Println(s1 == nil) // 空 相当于没有开辟内存空间
	fmt.Println(s2 == nil)

	// 初始化
	s1 = []int{1, 2, 3}
	s2 = []string{"沙河", "张江", "平山村"}

	fmt.Println(s1, s2)

	// 切片的长度和容量
	// len() 长度  cap() 容量

	fmt.Printf("len(s1):%d cap(s2):%d\n", len(s1), cap(s1))
	fmt.Printf("len(s1):%d cap(s2):%d\n", len(s2), cap(s2))

	// 由数组得到切片
	a1 := [...]int{1, 3, 5, 7, 9, 11, 13}
	s3 := a1[0:4] // [1, 3, 5, 7]  基于一个数组切割，左包含右不包含（左闭右开）
	fmt.Println(s3)

	s5 := a1[:4] // => [0:4]
	s6 := a1[3:] // => [3:len(a1)]
	s7 := a1[:]  // => [0:len(a1)]
	fmt.Println(s5, s6, s7)

	fmt.Printf("------ \n")
	// 切片的容量是指底层数组的容量
	fmt.Printf("len(s5): %d cap(s5): %d\n", len(s5), cap(s5))
	// 切片容量: 底层数组从切片 切的第一个元素到最后的元素数量
	// 容量总结
	// 切片指向了一个底层的数组。 切片的长度就是元素的个数。 切片的容量是底层
	// 数组从切片的第一个元素到最后一个元素的数量。
	fmt.Printf("len(s6): %d cap(s6): %d\n", len(s6), cap(s6))

	// 切片再切割
	// 切片是一个引用类型，都指向了一个底层数据
	s8 := s6[3:]
	fmt.Printf("len(s8): %d cap(s8): %d\n", len(s8), cap(s8))
	fmt.Println(s6)
	a1[6] = 1300
	fmt.Println("s6", s6)
	fmt.Println("s8", s8)

}
